﻿using GoodDotNet.Data.Models;
using GoodDotNet.Core.Model;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace GoodDotNet.App.AuthHelper.Policys
{
    /// <summary>
    /// JWTToken生成类
    /// </summary>
    public class JwtToken
    {
        public Audiences _audiences;
        private readonly SymmetricSecurityKey signingKey;
        public JwtToken(Audiences audiences)
        {
            _audiences = audiences;
            //读取配置文件
            var symmetricKeyAsBase64 = _audiences.Secret;
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            signingKey = new SymmetricSecurityKey(keyByteArray);
        }
        public TokenValidationParameters MakeTokenValidationParameters()
        {

            var tokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = signingKey,
                ValidateIssuer = true,
                ValidIssuer = _audiences.Issuer,//发行人
                ValidateAudience = true,
                ValidAudience = _audiences.Audience,//订阅人
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromSeconds(30),
                RequireExpirationTime = true,
            };
            return tokenValidationParameters;
        }
        /// <summary>
        /// 创建token
        /// </summary>
        /// <param name="Name">用户名称</param>
        /// <param name="Id">用户id</param>
        /// <param name="Site">用户站点</param>
        /// <param name="Roles">用户角色</param>
        /// <param name="RoleGrade">用户权限</param>
        /// <returns></returns>
        ///

        public dynamic BuildJwtToken(string Name, string Id, string Roles)
        {
            // 创建JWT头部
            var header = new JwtHeader(new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256));

            // 创建JWT有效载荷
            var claims = new List<Claim>();
            claims.Add(new Claim(ClaimTypes.Name, Name));
            claims.Add(new Claim(ClaimTypes.Role, Roles));
            claims.Add(new Claim("id", Id));
            //claims.Add(new Claim("site", Site));
            //claims.Add(new Claim("RoleGrade", RoleGrade));

            var payload = new JwtPayload(
                issuer: _audiences.Issuer,
                audience: _audiences.Audience,
                claims: claims,
                notBefore: DateTime.UtcNow,
                expires: DateTime.UtcNow.AddDays(1));

            // 创建JWT
            var jwt = new JwtSecurityToken(header, payload);


            // 生成 Token
            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            //打包返回前台
            var responseJson = new
            {
                success = true,
                token = encodedJwt,
                expires_in = 7200,
                token_type = "Bearer"

            };
            return responseJson;
        }
        public ClaimsPrincipal GetPrincipal(string token)
        {
            try
            {
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_audiences.Secret));
                var tokenHandler = new JwtSecurityTokenHandler();
                return new ClaimsPrincipal(tokenHandler.ValidateToken(token, MakeTokenValidationParameters(), out var validatedToken));
            }
            catch
            {
                return null;
            }
        }
        public int? ReadToken(HttpContext context)
        {
            var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
            var tokenHandler = new JwtSecurityTokenHandler();
            var info = tokenHandler.ReadJwtToken(token);
            TimeSpan difference = info.ValidTo.Subtract(DateTime.Now);
            if (difference.TotalDays > 2)
            {
                return null;
            }
            else
            {
                return Convert.ToInt32(info.Claims.FirstOrDefault(c => c.Type == "id")?.Value);
            }


        }
    }
}
